Here we will look at how to create a local git repository (repo) and connect it to an RStudio project. RStudio provides a nice GUI (Graphical User Interface) for interacting with git. It is also possible to write git commands directly into the terminal, however, here we will focus on using the GUI.

1 Installing Git

Before we can begin setting up a Git project you must first ensure that Git (not GitHub!) is installed on your machine. This is fairly straightforward, follow the OS specific installation instructions here: https://git-scm.com/downloads. Then restart your RStudio session.

2 Creating a Local Repo with RStudio

In order to create a local repo to manage our R files, we must create a new RStudio project.

Navigate to the ‘File’ tab and select ‘New Project…’. Navigate to the ‘File’ tab. Then select ‘New Directory’. Select ‘New Project,,,’ Select ‘New Project…’ Now choose a name for your git repo and tell RStudio which directory to place it in. Ensure you tick the ‘Create a git repository’ box. After clicking ‘Create Project’, RStudio will buffer before creating and opening the new project/git repo. Once the new project has opened, you should see a few new items displayed (marked in red below). We will come to these in the next section.

3 Version Control with Git and RStudio

Now that we have created our local repo, we can start coding and use git to manage our changes over time. Let’s start by creating a new file named ‘main.R’ and printing some text. Notice that after creating and saving ‘main.R’, the file shows up in our file manager (bottom right) and also in the ‘Git’ tab (top right). Next to these files we see yellow icons with question marks. This indicates that these files are new and we haven’t told git to track them yet.

3.1 Commiting Files

If we want git to track versions of a file then we must ‘commit’ the file. Each time we make a commit for a file, git creates and tracks a new version of that file. Remember, commits should be:

  • Minimal: A commit should only contain changes which relate to a single problem. Therefore, committing frequently is best.
  • Descriptive: Always include a commit message/description. This should be concise, describe the change you made and the reason for it.

To commit ‘main.R’ we navigate to the git drop down menu and select ‘commit’. This will open a ‘Review Changes’ box (shown below). On the top left, we see files available to commit. After selecting ‘main.R’, the yellow bow should switch to green with an ‘A’ inside. This indicates that the file is ready to be accepted/committed. On the top right will be a box where you can leave a commit comment (which you should always do). In the bottom panel will be a section of code highlighted either green (for code you have added) or red (for code you have deleted). Finally, click ‘Commit’. After committing, you will see that ‘main.R’ has disappeared from the ‘Git’ tab on the top right.

3.2 Modifying Files

Now let’s modify ‘main.R’ to contain some actual code. After saving the changes you should see ‘main.R’ reappear in the ‘Git’ tab. It will have a blue box with an ‘M’ inside, indicating that the file has now been modified (see below). After committing the modified file, it will again disappear from the ‘Git’ tab. We have now created a second version of ‘main.R’.

3.3 Reverting Files

Occasionally we may try to modify our code and end up breaking it completely. When not using git you might press ‘ctrl-z’ a bunch of times to revert it back to its working state. However, this won’t work if you’ve closed the editor/file. One of the big advantages to version control is the ability to revert your files back to a previous working version. Below I have added and committed some broken code to ‘main.R’. Now if we wish to undo these changes and go back to a previous version of the file we first select ‘History’ in the ‘Git’ tab on the top right. This will open a box detailing all of your commits. Now just navigate to the version you wish to revert to and select ‘View file @ …’ (see below). This will open the file in a new window. Now just save the file under the same name. The code in your editor will now be reverted to this version and you can recommit the corrected code.

3.4 Ignoring Files

Sometimes we may have files which we do not want git to track. For example, large unreadable data files or output files you are using to test your code. In this case we can tell git to ‘ignore’ these files by adding them to the ‘.gitignore’ file. In RStudio it is even easier as we can just tick the file we want to ignore in the ‘Git’ panel and select ‘ignore’ (see below). After clicking ignore, RStudio will display a box showing the contents of ‘.gitignore’. After saving and un-ticking the file it should disappear from the ‘Git’ panel on the top right.

3.5 Branching and Merging

Branching is used when you want to work on some new code which may be quite unstable and break easily. Therefore, rather than commit this to the master branch and risk breaking your existing code (which others may be using), you can create a branch. Once the code on your branch is finished and more stable, you can then merge it with the main branch again. Although merging may require you to resolve conflicts in the lines of code with the main branch.

Creating and switching between branches in RStudio is quite simple. To create a branch, simply select ‘New Branch’ and enter your branch name. If you are synced with GitHub (to be covered in the next worksheet), you should also tick ‘Sync branch with remote’.

This will create and switch you onto the new branch.You can switch between the branches using the drop down menu next to ‘New Branch’. After committing a few changes on each branch, you can check the ‘History’ tab and select all branches (see below).

Notice the master branch in red (main) and our new branch in green. Although it may appear as though one branch is ahead of the other, this is not the case, the branches evolve independently of each other.

However, you cannot remain on a branch forever. Branches should always be temporary and as soon as it is safe to do so, you need to merge your branch with the master branch. This is where the RStudio GUI falls short - there is no button/option for merging. We must do this manually using git commands in the terminal (don’t worry it’s quite simple). To merge our new branch with the master branch:

  1. Ensure you are currently on the master branch (see top right below). Or in git talk, ensure the master branch is checked out.
  2. Switch from the R Console to the terminal (see bottom left below).
  3. In the terminal, enter the command ‘git merge branch_name’.

In my case, git has issued us an error message. The most up to date code on the master branch is not in sync with the most up to date code on our separate branch. We must manually resolve the code in ‘main.R’ and recommit the changes on the master branch.

Once you have resolved and recommitted the changes, you should now see that the branches have merged in the git history tab (see below).

LS0tDQp0aXRsZTogIkNyZWF0aW5nIGEgTG9jYWwgR2l0IFJlcG9zaXRvcnkgd2l0aCBSU3R1ZGlvIg0KYXV0aG9yOiAiQ2Fyc29uIE1jS2VlIg0KZGF0ZTogIjIwMjQtMDQtMjIiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAnMicNCiAgICBkZl9wcmludDogcGFnZWQNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDINCiAgICB0b2NfZmxvYXQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOg0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KSGVyZSB3ZSB3aWxsIGxvb2sgYXQgaG93IHRvIGNyZWF0ZSBhIGxvY2FsIGdpdCByZXBvc2l0b3J5IChyZXBvKSBhbmQgY29ubmVjdCBpdCB0byBhbiBSU3R1ZGlvIHByb2plY3QuIFJTdHVkaW8gcHJvdmlkZXMgYSBuaWNlIEdVSSAoR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlKSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBnaXQuIEl0IGlzIGFsc28gcG9zc2libGUgdG8gd3JpdGUgZ2l0IGNvbW1hbmRzIGRpcmVjdGx5IGludG8gdGhlIHRlcm1pbmFsLCBob3dldmVyLCBoZXJlIHdlIHdpbGwgZm9jdXMgb24gdXNpbmcgdGhlIEdVSS4NCg0KIyBJbnN0YWxsaW5nIEdpdA0KQmVmb3JlIHdlIGNhbiBiZWdpbiBzZXR0aW5nIHVwIGEgR2l0IHByb2plY3QgeW91IG11c3QgZmlyc3QgZW5zdXJlIHRoYXQgR2l0IChub3QgR2l0SHViISkgaXMgaW5zdGFsbGVkIG9uIHlvdXIgbWFjaGluZS4gVGhpcyBpcyBmYWlybHkgc3RyYWlnaHRmb3J3YXJkLCBmb2xsb3cgdGhlIE9TIHNwZWNpZmljIGluc3RhbGxhdGlvbiBpbnN0cnVjdGlvbnMgaGVyZTogPGh0dHBzOi8vZ2l0LXNjbS5jb20vZG93bmxvYWRzPi4gVGhlbiByZXN0YXJ0IHlvdXIgUlN0dWRpbyBzZXNzaW9uLiANCg0KIyBDcmVhdGluZyBhIExvY2FsIFJlcG8gd2l0aCBSU3R1ZGlvDQpJbiBvcmRlciB0byBjcmVhdGUgYSBsb2NhbCByZXBvIHRvIG1hbmFnZSBvdXIgUiBmaWxlcywgd2UgbXVzdCBjcmVhdGUgYSBuZXcgUlN0dWRpbyBwcm9qZWN0Lg0KDQpOYXZpZ2F0ZSB0byB0aGUgJ0ZpbGUnIHRhYiBhbmQgc2VsZWN0ICdOZXcgUHJvamVjdC4uLicuDQohW05hdmlnYXRlIHRvIHRoZSAnRmlsZScgdGFiLl0oZ2l0XzEucG5nKQ0KVGhlbiBzZWxlY3QgJ05ldyBEaXJlY3RvcnknLg0KIVtTZWxlY3QgJ05ldyBQcm9qZWN0LCwsJ10oZ2l0XzIucG5nKQ0KU2VsZWN0ICdOZXcgUHJvamVjdC4uLicNCiFbXShnaXRfMy5wbmcpDQpOb3cgY2hvb3NlIGEgbmFtZSBmb3IgeW91ciBnaXQgcmVwbyBhbmQgdGVsbCBSU3R1ZGlvIHdoaWNoIGRpcmVjdG9yeSB0byBwbGFjZSBpdCBpbi4gKipFbnN1cmUgeW91IHRpY2sgdGhlICdDcmVhdGUgYSBnaXQgcmVwb3NpdG9yeScgYm94KiouDQohW10oZ2l0XzQucG5nKQ0KQWZ0ZXIgY2xpY2tpbmcgJ0NyZWF0ZSBQcm9qZWN0JywgUlN0dWRpbyB3aWxsIGJ1ZmZlciBiZWZvcmUgY3JlYXRpbmcgYW5kIG9wZW5pbmcgdGhlIG5ldyBwcm9qZWN0L2dpdCByZXBvLiBPbmNlIHRoZSBuZXcgcHJvamVjdCBoYXMgb3BlbmVkLCB5b3Ugc2hvdWxkIHNlZSBhIGZldyBuZXcgaXRlbXMgZGlzcGxheWVkIChtYXJrZWQgaW4gcmVkIGJlbG93KS4gV2Ugd2lsbCBjb21lIHRvIHRoZXNlIGluIHRoZSBuZXh0IHNlY3Rpb24uDQohW10oZ2l0XzUucG5nKQ0KDQojIFZlcnNpb24gQ29udHJvbCB3aXRoIEdpdCBhbmQgUlN0dWRpbw0KTm93IHRoYXQgd2UgaGF2ZSBjcmVhdGVkIG91ciBsb2NhbCByZXBvLCB3ZSBjYW4gc3RhcnQgY29kaW5nIGFuZCB1c2UgZ2l0IHRvIG1hbmFnZSBvdXIgY2hhbmdlcyBvdmVyIHRpbWUuIA0KTGV0J3Mgc3RhcnQgYnkgY3JlYXRpbmcgYSBuZXcgZmlsZSBuYW1lZCAnbWFpbi5SJyBhbmQgcHJpbnRpbmcgc29tZSB0ZXh0Lg0KIVtdKGdpdF82LnBuZykNCk5vdGljZSB0aGF0IGFmdGVyIGNyZWF0aW5nIGFuZCBzYXZpbmcgJ21haW4uUicsIHRoZSBmaWxlIHNob3dzIHVwIGluIG91ciBmaWxlIG1hbmFnZXIgKGJvdHRvbSByaWdodCkgYW5kIGFsc28gaW4gdGhlICdHaXQnIHRhYiAodG9wIHJpZ2h0KS4gTmV4dCB0byB0aGVzZSBmaWxlcyB3ZSBzZWUgeWVsbG93IGljb25zIHdpdGggcXVlc3Rpb24gbWFya3MuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlc2UgZmlsZXMgYXJlIG5ldyBhbmQgd2UgaGF2ZW4ndCB0b2xkIGdpdCB0byB0cmFjayB0aGVtIHlldC4NCg0KIyMgQ29tbWl0aW5nIEZpbGVzDQpJZiB3ZSB3YW50IGdpdCB0byB0cmFjayB2ZXJzaW9ucyBvZiBhIGZpbGUgdGhlbiB3ZSBtdXN0ICdjb21taXQnIHRoZSBmaWxlLiBFYWNoIHRpbWUgd2UgbWFrZSBhIGNvbW1pdCBmb3IgYSBmaWxlLCBnaXQgY3JlYXRlcyBhbmQgdHJhY2tzIGEgbmV3IHZlcnNpb24gb2YgdGhhdCBmaWxlLiANClJlbWVtYmVyLCBjb21taXRzIHNob3VsZCBiZToNCg0KKiAqKk1pbmltYWwqKjogQSBjb21taXQgc2hvdWxkIG9ubHkgY29udGFpbiBjaGFuZ2VzIHdoaWNoIHJlbGF0ZSB0byBhIHNpbmdsZSBwcm9ibGVtLiBUaGVyZWZvcmUsIGNvbW1pdHRpbmcgZnJlcXVlbnRseSBpcyBiZXN0LiANCiogKipEZXNjcmlwdGl2ZSoqOiBBbHdheXMgaW5jbHVkZSBhIGNvbW1pdCBtZXNzYWdlL2Rlc2NyaXB0aW9uLiBUaGlzIHNob3VsZCBiZSBjb25jaXNlLCBkZXNjcmliZSB0aGUgY2hhbmdlIHlvdSBtYWRlIGFuZCB0aGUgcmVhc29uIGZvciBpdC4NCg0KVG8gY29tbWl0ICdtYWluLlInIHdlIG5hdmlnYXRlIHRvIHRoZSBnaXQgZHJvcCBkb3duIG1lbnUgYW5kIHNlbGVjdCAnY29tbWl0Jy4NCiFbXShnaXRfNy5wbmcpDQpUaGlzIHdpbGwgb3BlbiBhICdSZXZpZXcgQ2hhbmdlcycgYm94IChzaG93biBiZWxvdykuIE9uIHRoZSB0b3AgbGVmdCwgd2Ugc2VlIGZpbGVzIGF2YWlsYWJsZSB0byBjb21taXQuIEFmdGVyIHNlbGVjdGluZyAnbWFpbi5SJywgdGhlIHllbGxvdyBib3cgc2hvdWxkIHN3aXRjaCB0byBncmVlbiB3aXRoIGFuICdBJyBpbnNpZGUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIGZpbGUgaXMgcmVhZHkgdG8gYmUgYWNjZXB0ZWQvY29tbWl0dGVkLiBPbiB0aGUgdG9wIHJpZ2h0IHdpbGwgYmUgYSBib3ggd2hlcmUgeW91IGNhbiBsZWF2ZSBhIGNvbW1pdCBjb21tZW50ICh3aGljaCB5b3Ugc2hvdWxkIGFsd2F5cyBkbykuIEluIHRoZSBib3R0b20gcGFuZWwgd2lsbCBiZSBhIHNlY3Rpb24gb2YgY29kZSBoaWdobGlnaHRlZCBlaXRoZXIgZ3JlZW4gKGZvciBjb2RlIHlvdSBoYXZlIGFkZGVkKSBvciByZWQgKGZvciBjb2RlIHlvdSBoYXZlIGRlbGV0ZWQpLiBGaW5hbGx5LCBjbGljayAnQ29tbWl0Jy4NCiFbXShnaXRfOC5wbmcpDQpBZnRlciBjb21taXR0aW5nLCB5b3Ugd2lsbCBzZWUgdGhhdCAnbWFpbi5SJyBoYXMgZGlzYXBwZWFyZWQgZnJvbSB0aGUgJ0dpdCcgdGFiIG9uIHRoZSB0b3AgcmlnaHQuDQohW10oZ2l0XzkucG5nKQ0KDQojIyBNb2RpZnlpbmcgRmlsZXMNCk5vdyBsZXQncyBtb2RpZnkgJ21haW4uUicgdG8gY29udGFpbiBzb21lIGFjdHVhbCBjb2RlLiBBZnRlciBzYXZpbmcgdGhlIGNoYW5nZXMgeW91IHNob3VsZCBzZWUgJ21haW4uUicgcmVhcHBlYXIgaW4gdGhlICdHaXQnIHRhYi4gSXQgd2lsbCBoYXZlIGEgYmx1ZSBib3ggd2l0aCBhbiAnTScgaW5zaWRlLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGZpbGUgaGFzIG5vdyBiZWVuIG1vZGlmaWVkIChzZWUgYmVsb3cpLg0KIVtdKGdpdF8xMC5wbmcpDQpBZnRlciBjb21taXR0aW5nIHRoZSBtb2RpZmllZCBmaWxlLCBpdCB3aWxsIGFnYWluIGRpc2FwcGVhciBmcm9tIHRoZSAnR2l0JyB0YWIuIFdlIGhhdmUgbm93IGNyZWF0ZWQgYSBzZWNvbmQgdmVyc2lvbiBvZiAnbWFpbi5SJy4NCg0KIyMgUmV2ZXJ0aW5nIEZpbGVzDQpPY2Nhc2lvbmFsbHkgd2UgbWF5IHRyeSB0byBtb2RpZnkgb3VyIGNvZGUgYW5kIGVuZCB1cCBicmVha2luZyBpdCBjb21wbGV0ZWx5LiBXaGVuIG5vdCB1c2luZyBnaXQgeW91IG1pZ2h0IHByZXNzICdjdHJsLXonIGEgYnVuY2ggb2YgdGltZXMgdG8gcmV2ZXJ0IGl0IGJhY2sgdG8gaXRzIHdvcmtpbmcgc3RhdGUuIEhvd2V2ZXIsIHRoaXMgd29uJ3Qgd29yayBpZiB5b3UndmUgY2xvc2VkIHRoZSBlZGl0b3IvZmlsZS4gT25lIG9mIHRoZSBiaWcgYWR2YW50YWdlcyB0byB2ZXJzaW9uIGNvbnRyb2wgaXMgdGhlIGFiaWxpdHkgdG8gcmV2ZXJ0IHlvdXIgZmlsZXMgYmFjayB0byBhIHByZXZpb3VzIHdvcmtpbmcgdmVyc2lvbi4gDQpCZWxvdyBJIGhhdmUgYWRkZWQgYW5kIGNvbW1pdHRlZCBzb21lIGJyb2tlbiBjb2RlIHRvICdtYWluLlInLg0KIVtdKGdpdF8xMS5wbmcpDQpOb3cgaWYgd2Ugd2lzaCB0byB1bmRvIHRoZXNlIGNoYW5nZXMgYW5kIGdvIGJhY2sgdG8gYSBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoZSBmaWxlIHdlIGZpcnN0IHNlbGVjdCAnSGlzdG9yeScgaW4gdGhlICdHaXQnIHRhYiBvbiB0aGUgdG9wIHJpZ2h0LiBUaGlzIHdpbGwgb3BlbiBhIGJveCBkZXRhaWxpbmcgYWxsIG9mIHlvdXIgY29tbWl0cy4gTm93IGp1c3QgbmF2aWdhdGUgdG8gdGhlIHZlcnNpb24geW91IHdpc2ggdG8gcmV2ZXJ0IHRvIGFuZCBzZWxlY3QgJ1ZpZXcgZmlsZSBAIC4uLicgKHNlZSBiZWxvdykuDQohW10oZ2l0XzEyLnBuZykNClRoaXMgd2lsbCBvcGVuIHRoZSBmaWxlIGluIGEgbmV3IHdpbmRvdy4gTm93IGp1c3Qgc2F2ZSB0aGUgZmlsZSB1bmRlciB0aGUgc2FtZSBuYW1lLg0KIVtdKGdpdF8xMy5wbmcpDQpUaGUgY29kZSBpbiB5b3VyIGVkaXRvciB3aWxsIG5vdyBiZSByZXZlcnRlZCB0byB0aGlzIHZlcnNpb24gYW5kIHlvdSBjYW4gcmVjb21taXQgdGhlIGNvcnJlY3RlZCBjb2RlLg0KDQojIyBJZ25vcmluZyBGaWxlcw0KU29tZXRpbWVzIHdlIG1heSBoYXZlIGZpbGVzIHdoaWNoIHdlIGRvIG5vdCB3YW50IGdpdCB0byB0cmFjay4gRm9yIGV4YW1wbGUsIGxhcmdlIHVucmVhZGFibGUgZGF0YSBmaWxlcyBvciBvdXRwdXQgZmlsZXMgeW91IGFyZSB1c2luZyB0byB0ZXN0IHlvdXIgY29kZS4gSW4gdGhpcyBjYXNlIHdlIGNhbiB0ZWxsIGdpdCB0byAnaWdub3JlJyB0aGVzZSBmaWxlcyBieSBhZGRpbmcgdGhlbSB0byB0aGUgJy5naXRpZ25vcmUnIGZpbGUuIEluIFJTdHVkaW8gaXQgaXMgZXZlbiBlYXNpZXIgYXMgd2UgY2FuIGp1c3QgdGljayB0aGUgZmlsZSB3ZSB3YW50IHRvIGlnbm9yZSBpbiB0aGUgJ0dpdCcgcGFuZWwgYW5kIHNlbGVjdCAnaWdub3JlJyAoc2VlIGJlbG93KS4NCiFbXShnaXRfMTQucG5nKQ0KQWZ0ZXIgY2xpY2tpbmcgaWdub3JlLCBSU3R1ZGlvIHdpbGwgZGlzcGxheSBhIGJveCBzaG93aW5nIHRoZSBjb250ZW50cyBvZiAnLmdpdGlnbm9yZScuIEFmdGVyIHNhdmluZyBhbmQgdW4tdGlja2luZyB0aGUgZmlsZSBpdCBzaG91bGQgZGlzYXBwZWFyIGZyb20gdGhlICdHaXQnIHBhbmVsIG9uIHRoZSB0b3AgcmlnaHQuDQoNCiMjIEJyYW5jaGluZyBhbmQgTWVyZ2luZw0KQnJhbmNoaW5nIGlzIHVzZWQgd2hlbiB5b3Ugd2FudCB0byB3b3JrIG9uIHNvbWUgbmV3IGNvZGUgd2hpY2ggbWF5IGJlIHF1aXRlIHVuc3RhYmxlIGFuZCBicmVhayBlYXNpbHkuIFRoZXJlZm9yZSwgcmF0aGVyIHRoYW4gY29tbWl0IHRoaXMgdG8gdGhlIG1hc3RlciBicmFuY2ggYW5kIHJpc2sgYnJlYWtpbmcgeW91ciBleGlzdGluZyBjb2RlICh3aGljaCBvdGhlcnMgbWF5IGJlIHVzaW5nKSwgeW91IGNhbiBjcmVhdGUgYSAqYnJhbmNoKi4gDQpPbmNlIHRoZSBjb2RlIG9uIHlvdXIgYnJhbmNoIGlzIGZpbmlzaGVkIGFuZCBtb3JlIHN0YWJsZSwgeW91IGNhbiB0aGVuICptZXJnZSogaXQgd2l0aCB0aGUgbWFpbiBicmFuY2ggYWdhaW4uIEFsdGhvdWdoIG1lcmdpbmcgbWF5IHJlcXVpcmUgeW91IHRvIHJlc29sdmUgY29uZmxpY3RzIGluIHRoZSBsaW5lcyBvZiBjb2RlIHdpdGggdGhlIG1haW4gYnJhbmNoLg0KDQpDcmVhdGluZyBhbmQgc3dpdGNoaW5nIGJldHdlZW4gYnJhbmNoZXMgaW4gUlN0dWRpbyBpcyBxdWl0ZSBzaW1wbGUuIFRvIGNyZWF0ZSBhIGJyYW5jaCwgc2ltcGx5IHNlbGVjdCAnTmV3IEJyYW5jaCcgYW5kIGVudGVyIHlvdXIgYnJhbmNoIG5hbWUuIElmIHlvdSBhcmUgc3luY2VkIHdpdGggR2l0SHViICh0byBiZSBjb3ZlcmVkIGluIHRoZSBuZXh0IHdvcmtzaGVldCksIHlvdSBzaG91bGQgYWxzbyB0aWNrICdTeW5jIGJyYW5jaCB3aXRoIHJlbW90ZScuDQohW10oZ2l0XzE1LnBuZykNCg0KVGhpcyB3aWxsIGNyZWF0ZSBhbmQgc3dpdGNoIHlvdSBvbnRvIHRoZSBuZXcgYnJhbmNoLllvdSBjYW4gc3dpdGNoIGJldHdlZW4gdGhlIGJyYW5jaGVzIHVzaW5nIHRoZSBkcm9wIGRvd24gbWVudSBuZXh0IHRvICdOZXcgQnJhbmNoJy4gQWZ0ZXIgY29tbWl0dGluZyBhIGZldyBjaGFuZ2VzIG9uIGVhY2ggYnJhbmNoLCB5b3UgY2FuIGNoZWNrIHRoZSAnSGlzdG9yeScgdGFiIGFuZCBzZWxlY3QgYWxsIGJyYW5jaGVzIChzZWUgYmVsb3cpLg0KIVtdKGdpdF8xNi5wbmcpDQoNCk5vdGljZSB0aGUgbWFzdGVyIGJyYW5jaCBpbiByZWQgKG1haW4pIGFuZCBvdXIgbmV3IGJyYW5jaCBpbiBncmVlbi4gQWx0aG91Z2ggaXQgbWF5IGFwcGVhciBhcyB0aG91Z2ggb25lIGJyYW5jaCBpcyAqYWhlYWQqIG9mIHRoZSBvdGhlciwgdGhpcyBpcyBub3QgdGhlIGNhc2UsIHRoZSBicmFuY2hlcyBldm9sdmUgaW5kZXBlbmRlbnRseSBvZiBlYWNoIG90aGVyLiANCg0KSG93ZXZlciwgeW91IGNhbm5vdCByZW1haW4gb24gYSBicmFuY2ggZm9yZXZlci4gQnJhbmNoZXMgc2hvdWxkIGFsd2F5cyBiZSB0ZW1wb3JhcnkgYW5kIGFzIHNvb24gYXMgaXQgaXMgc2FmZSB0byBkbyBzbywgeW91IG5lZWQgdG8gbWVyZ2UgeW91ciBicmFuY2ggd2l0aCB0aGUgbWFzdGVyIGJyYW5jaC4gVGhpcyBpcyB3aGVyZSB0aGUgUlN0dWRpbyBHVUkgZmFsbHMgc2hvcnQgLSB0aGVyZSBpcyBubyBidXR0b24vb3B0aW9uIGZvciBtZXJnaW5nLiBXZSBtdXN0IGRvIHRoaXMgbWFudWFsbHkgdXNpbmcgZ2l0IGNvbW1hbmRzIGluIHRoZSB0ZXJtaW5hbCAoZG9uJ3Qgd29ycnkgaXQncyBxdWl0ZSBzaW1wbGUpLiANClRvIG1lcmdlIG91ciBuZXcgYnJhbmNoIHdpdGggdGhlIG1hc3RlciBicmFuY2g6DQoNCjEuIEVuc3VyZSB5b3UgYXJlIGN1cnJlbnRseSBvbiB0aGUgbWFzdGVyIGJyYW5jaCAoc2VlIHRvcCByaWdodCBiZWxvdykuIE9yIGluIGdpdCB0YWxrLCBlbnN1cmUgdGhlIG1hc3RlciBicmFuY2ggaXMgY2hlY2tlZCBvdXQuDQoyLiBTd2l0Y2ggZnJvbSB0aGUgUiBDb25zb2xlIHRvIHRoZSB0ZXJtaW5hbCAoc2VlIGJvdHRvbSBsZWZ0IGJlbG93KS4NCjMuIEluIHRoZSB0ZXJtaW5hbCwgZW50ZXIgdGhlIGNvbW1hbmQgJ2dpdCBtZXJnZSBicmFuY2hfbmFtZScuDQoNCiFbXShnaXRfMTcucG5nKQ0KDQpJbiBteSBjYXNlLCBnaXQgaGFzIGlzc3VlZCB1cyBhbiBlcnJvciBtZXNzYWdlLiBUaGUgbW9zdCB1cCB0byBkYXRlIGNvZGUgb24gdGhlIG1hc3RlciBicmFuY2ggaXMgbm90IGluIHN5bmMgd2l0aCB0aGUgbW9zdCB1cCB0byBkYXRlIGNvZGUgb24gb3VyIHNlcGFyYXRlIGJyYW5jaC4gV2UgbXVzdCBtYW51YWxseSByZXNvbHZlIHRoZSBjb2RlIGluICdtYWluLlInIGFuZCByZWNvbW1pdCB0aGUgY2hhbmdlcyBvbiB0aGUgbWFzdGVyIGJyYW5jaC4NCg0KIVtdKGdpdF8xOC5wbmcpDQoNCk9uY2UgeW91IGhhdmUgcmVzb2x2ZWQgYW5kIHJlY29tbWl0dGVkIHRoZSBjaGFuZ2VzLCB5b3Ugc2hvdWxkIG5vdyBzZWUgdGhhdCB0aGUgYnJhbmNoZXMgaGF2ZSBtZXJnZWQgaW4gdGhlIGdpdCBoaXN0b3J5IHRhYiAoc2VlIGJlbG93KS4NCg0KIVtdKGdpdF8xOS5wbmcpDQo=